package com.ruoyi.cs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.pay.HttpsUtils;
import com.ruoyi.common.utils.pay.PayjsConfig;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.TRecharge;
import com.ruoyi.cs.domain.TUser;
import com.ruoyi.cs.domain.TUserAuthentication;
import com.ruoyi.cs.domain.vo.SomisspayVo;
import com.ruoyi.cs.mapper.TRechargeMapper;
import com.ruoyi.cs.mapper.TUserAuthenticationMapper;
import com.ruoyi.cs.mapper.TUserMapper;
import com.ruoyi.cs.service.CommonService;
import com.ruoyi.cs.service.IJiuJiaPayService;
import com.ruoyi.cs.service.IYouMiYunPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Service
@SuppressWarnings("all")
public class YouMiYunServiceImpl implements IYouMiYunPayService {
    private Logger log = LoggerFactory.getLogger(YouMiYunServiceImpl.class);
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private TRechargeMapper tRechargeMapper;
    @Value("${ruoyi.ymypayNotify}")
    private String cznotify;
    @Value("${ruoyi.returnUrl}")
    private String returnUrl;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private TUserAuthenticationMapper tUserAuthenticationMapper;

    public String risk(String orderId,String extraAccountCertnoLastSix,String extraAccountPhoneLastTwo,String desensitizedUid){
        Map<String, String> payData = new HashMap<>();
        payData.put("version", "1.0");
        payData.put("customerid", PayjsConfig.customerid);
        payData.put("sdorderno", orderId);
        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
        payData.put("mcCreateTradeIp", ip);
        /**用户证件号后6位明文	*/
        payData.put("extraAccountCertnoLastSix", extraAccountCertnoLastSix);
        /**用户手机号后2位明文	*/
        payData.put("extraAccountPhoneLastTwo",extraAccountPhoneLastTwo);
        /**用户ID	*/
        payData.put("desensitizedUid", desensitizedUid);
        payData.put("mcCreateTradeTime", DateUtils.getTime());
        String sign = commonService.sign(payData, PayjsConfig.apikey);
        payData.put("sign",sign);
        String result = HttpsUtils.http(PayjsConfig.riskUrl, payData);
        return result;
    }


    @Override
    public Response<Map> recharge(String userId, BigDecimal czMoney, String czEquipment) throws Exception {
        TUser tUser = tUserMapper.selectTUserById(userId);
        TUserAuthentication tUserAuthentication = tUserAuthenticationMapper.selectTUserAuthenticationByUserId(tUser.getUserId().toString());
        if (tUserAuthentication == null){
            /**满足触发实名认证*/
            return  Response.fail("请先实名认证！");
        }
        String out_trade_no = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 8);
        String extraAccountCertnoLastSix = tUserAuthentication.getIdcard().substring(tUserAuthentication.getIdcard().length()-6);
        String riskstr = this.risk(out_trade_no,extraAccountCertnoLastSix,tUser.getUserPhone().substring(tUser.getUserPhone().length()-2),tUser.getUserId().toString());
        if (!"success".equalsIgnoreCase(riskstr)){
            log.error("优米云风控报备接口返回失败:{}",riskstr);
            return Response.fail("充值报备请求失败");
        }
        BigDecimal giveFee = new BigDecimal("0");
        try {
            giveFee = commonService.rechargeVerification(tUser, czMoney);
        } catch (Exception e) {
            return Response.fail(e.getMessage());
        }
        BigDecimal fee = czMoney.multiply(new BigDecimal(6.5)).setScale(2, BigDecimal.ROUND_HALF_UP);
        Long starttime = System.currentTimeMillis();

        Map<String, String> payData = new HashMap<>();
        payData.put("version", "1.0");
        payData.put("customerid", PayjsConfig.customerid);
        payData.put("sdorderno", out_trade_no);
        payData.put("totalfee", fee.toString());
        payData.put("paytype", "alipaywap");
        payData.put("notifyurl",cznotify);
        payData.put("returnurl", returnUrl);
        payData.put("ip", DateUtils.getTime());
        payData.put("qrtype","string");
        String sign = commonService.signJH(payData, PayjsConfig.apikey);

        payData.put("sign",sign);
        System.out.println("签名:"+payData.get("sign"));
        /**发送请求*/
        String result = HttpsUtils.http(PayjsConfig.somisspayUrl, payData);
        if(result == null || !result.startsWith("https")){
            return Response.fail("充值接口响应失败");
        }
        log.info("优米云充值发送请求时间:{}",System.currentTimeMillis()-starttime);
        String picurl = null;
        try {
            /**生产二维码图片*/
            picurl = commonService.scQrCodeImge(result);
        } catch (Exception e) {
            log.error("九嘉支付生产二维码订单异常:{}", e.getMessage());
            e.printStackTrace();
            return Response.fail("发送请求失败");
        }

        TRecharge tRecharge = new TRecharge();
        tRecharge.setUserId(userId);
        tRecharge.setCzId(out_trade_no);
        tRecharge.setDelFlag(Constants.SUCCESS);
        tRecharge.setCzType(Constants.ALIPAY);
        tRecharge.setMerchantOrderNo(out_trade_no);
        /**支付结果  0 待充值 1充值成功 2充值失败*/
        tRecharge.setCzStatus(Constants.CZSTATUS0);
        /**交易类型*/
        tRecharge.setCzEquipment(czEquipment);
        tRecharge.setCreateTime(DateUtils.getNowDate());
        tRecharge.setGiveFee(giveFee);
        tRecharge.setCzMoney(czMoney);
        tRecharge.setCzPlatform(Constants.CZPLATFORM6);
        tRecharge.setUserType(tUser.getUserType());
        if (StringUtils.isNotEmpty(tUser.getUserPromotersId())) {
            tRecharge.setUserPromotersId(tUser.getUserPromotersId());
        }
        int count = tRechargeMapper.insertTRecharge(tRecharge);
        if (count > 0) {
            Map resultMap = new HashMap();
            resultMap.put("picUrl", picurl);
            resultMap.put("czId", out_trade_no);
            resultMap.put("totalFee", czMoney);
            resultMap.put("url", result);
            log.info("优米云支付订单生产：参数信息：{}，支付金额：{},订单号：{}", JSON.toJSONString(tRecharge), fee, out_trade_no);
            return Response.success(resultMap);
        } else {
            log.error("优米云支付充值记录表插入失败：参数信息：{}，支付金额：{},订单号：{}", JSON.toJSONString(tRecharge), fee, out_trade_no);
            return Response.fail("充值窗口异常，请联系管理员处理!");
        }
    }

    @Override
    public String notify(SomisspayVo vo) {
        log.info("优米云支付异步通知:{}",vo.toString());
        String msg = vo.toString();
        try {
            Map<String, String> notifyData = new HashMap<>();
            notifyData.put("customerid", vo.getCustomerid());
            notifyData.put("totalfee", vo.getTotalfee());
            notifyData.put("sdorderno", vo.getSdorderno());
            notifyData.put("sdpayno", vo.getSdpayno());
            notifyData.put("paytype", vo.getPaytype());

            String sign = commonService.signJHNotify(notifyData, PayjsConfig.apikey);
            if (sign.equals(vo.getSign())){
                String sdorderno = vo.getSdorderno();
                TRecharge tRecharge = tRechargeMapper.selectTRechargeById(sdorderno);
                String platform = tRecharge == null ? "" : tRecharge.getCzPlatform();
                log.info("优米云支付回调签名认证成功");
                if (tRecharge != null) {
                    BigDecimal bg = tRecharge.getCzMoney();
                    BigDecimal fee = bg.multiply(new BigDecimal(6.5)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    if (new BigDecimal(vo.getTotalfee()).compareTo(new BigDecimal(fee.toString())) == 0) {
                        if(Constants.CZSTATUS0.equals(tRecharge.getCzStatus())){
                            commonService.czSuccessHandle(tRecharge,sdorderno, vo.getSdpayno(),msg);
                        }
                        return "success";
                    }else {
                        commonService.czFailHandle(tRecharge,sdorderno,vo.getSdpayno(),msg);
                        return "success";
                    }
                } else {
                    log.error("查询充值订单信息为空,请求参数：{}", msg);
                    return "fail";
                }
            } else {
                log.info("富信回调签名认证失败，signVerified=false, paramsJson:{}", msg);
                return "fail";
            }
        } catch (Exception e) {
            log.error("回调异常,paramsJson:{},errorMsg:{}", msg, e.getMessage());
            return "fail";
        }
    }
}
